package com.watchthelan.repository;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;

import com.watchthelan.domain.Administrator;

public class JdbcAdministratorDao extends SimpleJdbcDaoSupport implements AdministratorDao {
	/** Logger for this class and subclasses */
	protected final Log logger = LogFactory.getLog(getClass());

	@Override
	public void addAdministrator(Administrator administrator) {
		logger.info("adding administrator: " + administrator);
		int id = getSimpleJdbcTemplate().queryForInt("select max(id) from administrators", new HashMap<String, String>()) + 1;
		logger.info("next id: " + id);
		int count = getSimpleJdbcTemplate().update(
				"insert into administrators (id, username, password, name, enabled, email, phone, address) values(:id, :username, :password, :name, :enabled, :email, :phone, :address)",
				new MapSqlParameterSource().addValue("id", id)
				.addValue("username", administrator.getUsername())
				.addValue("password", administrator.getPassword())
				.addValue("name", administrator.getName())
				.addValue("enabled", administrator.getEnabled())
				.addValue("email", administrator.getEmail())
				.addValue("phone", administrator.getPhone())
				.addValue("address", administrator.getAddress()));
		logger.info("Rows affected: " + count);
	}

	@Override
	public void deleteAdministratorById(Long id) {
		logger.info("deleting admin with id " + id);
		int count = getSimpleJdbcTemplate().update(
				"delete from administrators where id=:id",
				new MapSqlParameterSource().addValue("id", id));
		logger.info("Rows affected: " + count);
	}

	@Override
	public Administrator getAdministratorById(Long id) {
		logger.info("get administrator by id");
		if (id == null) {
			logger.info("administrator id is null");
			return null;
		}
		Administrator administrator = null;
		List<Administrator> administratorList =getSimpleJdbcTemplate().query("select * from administrators where id=?", 
				new ParameterizedRowMapper<Administrator>() {
			public Administrator mapRow(ResultSet rs, int rowNum)
			throws SQLException {
				Administrator administrator = new Administrator();
				administrator.setName(rs.getString("name"));
				administrator.setUsername(rs.getString("username"));
				administrator.setPassword(rs.getString("password"));
				administrator.setEnabled(rs.getBoolean("enabled"));
				administrator.setEmail(rs.getString("email"));
				administrator.setPhone(rs.getString("phone"));
				administrator.setAddress(rs.getString("address"));
				return administrator;
			}
		}, id); 
		if (administratorList != null && administratorList.size() > 0) {
			administrator = administratorList.get(0);
			administrator.setId(id);
			logger.info("got administrator: " + administrator);
		}
		return administrator;
	}

	@Override
	public List<Administrator> getAdministrators() {
		logger.info("get administrators");
		List<Administrator> administrators = getSimpleJdbcTemplate().query("select id, username, password, name, enabled, email, phone, address from administrators", new AdministratorMapper());		
		return administrators;
	}

	@Override
	public void updateAdministrator(Administrator administrator) {
		logger.info("updating administrator: " + administrator);
		int count = getSimpleJdbcTemplate().update(
				"update administrators set id=:id, username=:username, password=:password, name=:name, enabled=:enabled, email=:email, phone=:phone, address=:address  where id=:id",
				new MapSqlParameterSource().addValue("id", administrator.getId())
				.addValue("name", administrator.getName())
				.addValue("username", administrator.getUsername())
				.addValue("password", administrator.getPassword())
				.addValue("name", administrator.getName())
				.addValue("enabled", administrator.getEnabled())
				.addValue("email", administrator.getEmail())
				.addValue("phone", administrator.getPhone())
				.addValue("address", administrator.getAddress()));
		logger.info("Rows affected: " + count);
	}

	private static class AdministratorMapper implements ParameterizedRowMapper<Administrator> {

		public Administrator mapRow(ResultSet rs, int arg1) throws SQLException {
			Administrator administrator = new Administrator();
			administrator.setId(rs.getLong("id"));
			administrator.setName(rs.getString("name"));
			administrator.setUsername(rs.getString("username"));
			administrator.setPassword(rs.getString("password"));
			administrator.setEnabled(rs.getBoolean("enabled"));
			administrator.setEmail(rs.getString("email"));
			administrator.setPhone(rs.getString("phone"));
			administrator.setAddress(rs.getString("address"));
			return administrator;
		}

	}

	@Override
	public Administrator getAdministratorByUsername(String username) {
		logger.info("get administrator by username");
		if (username == null) {
			logger.info("administrator username is null");
			return null;
		}
		Administrator administrator = null;
		List<Administrator> administratorList = getSimpleJdbcTemplate().query("select * from administrators where username=?", 
				new ParameterizedRowMapper<Administrator>() {
			public Administrator mapRow(ResultSet rs, int rowNum)
			throws SQLException {
				Administrator administrator = new Administrator();
				administrator.setId(rs.getInt("id"));
				administrator.setName(rs.getString("name"));
				administrator.setPassword(rs.getString("password"));
				administrator.setEnabled(rs.getBoolean("enabled"));
				administrator.setEmail(rs.getString("email"));
				administrator.setPhone(rs.getString("phone"));
				administrator.setAddress(rs.getString("address"));
				return administrator;
			}
		}, username);
		if (administratorList != null && administratorList.size() > 0) {
			administrator = administratorList.get(0);
			administrator.setUsername(username);
			logger.info("got administrator: " + administrator);
		}
		return administrator;
	}
}
